using System;
using NUnit.Framework;

namespace NAsserter.Tests
{
    public class AssertThat_combinations : AssertionHelper
    {
        [Test]
        public void where_none_object_exists_with_false_if_and_invalid_second_assertion_1()
        {
            var entity = new TestEntity { Id = 7 };

            Expect(
                () => AssertThat
                        .Argument(entity, "testComparable")
                        .If(x => x.Id != 7)
                            .Property(x => x.Id, "Id")
                                .Assertions(x => x.Exists(new[] { 4, 5, 6 }))
                        .Argument(string.Empty, "username")
                            .If(true)
                            .IsNotNullOrEmpty(),
                Throws.ArgumentException.With.Message.Contains("username"));
        }

        [Test]
        public void where_none_object_exists_with_false_if_and_invalid_second_assertion_2()
        {
            var entity = new TestEntity { Id = 7 , Amount = 200};

            Expect(
                () => AssertThat
                        .Argument(entity, "testComparable")
                        .If(x => x.Id != 7)
                            .Property(x => x.Id, "Id").Assertions(x => x.Exists(4, 5, 6))
                        .Argument(string.Empty, "username")
                            .If(x => x.Length == 0)
                            .IsNotNullOrEmpty(),
                Throws.ArgumentException.With.Message.Contains("username"));
        }

        [Test]
        public void valid_not_null_with_range()
        {
            var startEntity = new TestEntity { Id = 5 };
            var endEntity = new TestEntity { Id = 10 };
            var arg = new TestEntity { Id = 5 };

            AssertThat
                .Argument(arg, "arg1")
                    .IsNotNull()
                    .Between(startEntity).And(endEntity)
                .Argument(5, "arg2")
                    .Between(1).And(10);
        }

        [Test]
        public void invalid_not_null_with_range()
        {
            var startEntity = new TestEntity { Id = 5 };
            var endEntity = new TestEntity { Id = 10 };
            var arg = new TestEntity { Id = 4 };

            Expect(
            () => AssertThat
                    .Argument(arg, "arg1")
                        .IsNotNull()
                        .Between(startEntity).And(endEntity)
                    .Argument(5, "arg2")
                        .Between(1).And(10),
            Throws.TypeOf<ArgumentOutOfRangeException>().With.Message.Contains("arg1"));
        }

        [Test]
        public void invalid_not_null_with_range_2()
        {
            var startEntity = new TestEntity { Id = 5 };
            var endEntity = new TestEntity { Id = 10 };
            var arg = new TestEntity { Id = 5 };

            Expect(
            () => AssertThat
                    .Argument(arg, "arg1")
                        .IsNotNull()
                        .Between(startEntity).And(endEntity)
                    .Argument(11, "arg2")
                        .Between(1).And(10),
            Throws.TypeOf<ArgumentOutOfRangeException>().With.Message.Contains("arg2"));
        }

        [Test]
        public void invalid_not_null_with_range_3()
        {
            var startEntity = new TestEntity { Id = 5 };
            var endEntity = new TestEntity { Id = 10 };
            TestEntity arg = null; //new TestEntity { Id = 5 };

            Expect(
            () => AssertThat
                    .Argument(arg, "arg1")
                        .IsNotNull()
                        .Between(startEntity).And(endEntity)
                    .Argument(11, "arg2")
                        .Between(1).And(10),
            Throws.TypeOf<ArgumentNullException>().With.Message.Contains("arg1"));
        }
    }
}